package com.atguigu.yygh.sms.service.impl;

import com.atguigu.yygh.exception.YyghException;
import com.atguigu.yygh.result.ResultCodeEnum;
import com.atguigu.yygh.sms.service.SmsService;
import com.atguigu.yygh.sms.util.SmsProperties;
import com.atguigu.yygh.vo.msm.MsmVo;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.sms.v20190711.SmsClient;
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20190711.models.SendStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @author zr
 * @date 2021/12/16 19:09
 */

@Service
@Slf4j
public class SmsServiceImpl implements SmsService {
    @Resource
    private SmsProperties smsProperties;

    /**
     * 实现短信的发送
     *
     * @param phone
     * @param code
     */
    @Override
    public boolean send(String phone, String code) {
        // 对手机号进行判空
        if (StringUtils.isEmpty(phone)) {
            return false;
        }
        String jointMobile = "+86" + phone;
        String secretId = smsProperties.getSecretId();
        String secretKey = smsProperties.getSecretKey();
        //短信应用 ID
        String appid = smsProperties.getAppid();
        //短信签名内容
        String sign = smsProperties.getSign();
        //短信模板 ID
        String templateID = smsProperties.getTemplateID();
        //+86为国家码，182********为手机号，最多不要超过200个手机号

        String[] phoneNumbers = {jointMobile};
        //模板参数: 若无模板参数，则设置为空
        // 对应模板中{1}
        String[] templateParams = {code};
        try {
            //必要步骤： 实例化一个认证对象，入参需要传入腾讯云账户密钥对 secretId 和 secretKey
            Credential cred = new Credential(secretId, secretKey);

            ClientProfile clientProfile = new ClientProfile();
            //SDK 默认用 TC3-HMAC-SHA256 进行签名 非必要请不要修改该字段
            clientProfile.setSignMethod("HmacSHA256");
            // 实例化 SMS 的 client 对象 第二个参数是地域信息，可以直接填写字符串 ap-guangzhou，或者引用预设的常量
            SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
            //实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数 您可以直接查询 SDK 源码确定接口有哪些属性可以设置
            SendSmsRequest req = new SendSmsRequest();

            // 短信应用 ID: 在 [短信控制台] 添加应用后生成的实际 SDKAppID，例如1400006666
            req.setSmsSdkAppid(appid);

            // 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名，可登录 [短信控制台] 查看签名信息
            req.setSign(sign);

            //短信模板 ID: 必须填写已审核通过的模板 ID，可登录 [短信控制台] 查看模板 ID
            req.setTemplateID(templateID);

            //下发手机号码，采用 e.164 标准，+[国家或地区码][手机号] 例如+8613711112222
            req.setPhoneNumberSet(phoneNumbers);

            req.setTemplateParamSet(templateParams);

            // 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的 返回的 res 是一个SendSmsResponse 类的实例，与请求对象对应
            SendSmsResponse res = client.SendSms(req);
            //获取响应结果
            SendStatus[] sendStatusSet = res.getSendStatusSet();
            log.info("短信发送返回的响应：" + sendStatusSet[0].getCode());

            String codeInfo = "Ok";
            if (codeInfo.equals(sendStatusSet[0].getCode())) {
                return true;
            }
        } catch (TencentCloudSDKException e) {
            log.error("腾讯云短信发送sdk调用失败：" + e.getErrorCode() + "," + e.getMessage());
            throw new YyghException(ResultCodeEnum.CODE_ERROR);
        }
        return false;
    }

    /**
     * mq发送短信
     *
     * @param msmVo
     * @return
     */
    @Override
    public boolean send(MsmVo msmVo) {
        if (StringUtils.hasText(msmVo.getPhone())) {
            return this.send(msmVo.getPhone(), msmVo.getParam());
        }
        return false;
    }

    private boolean send(String phone, Map<String, Object> params) {
        // 对手机号进行判空
        if (StringUtils.isEmpty(phone)) {
            return false;
        }
        String jointMobile = "+86" + phone;
        String secretId = smsProperties.getSecretId();
        String secretKey = smsProperties.getSecretKey();
        //短信应用 ID
        String appid = smsProperties.getAppid();
        //短信签名内容
        String sign = smsProperties.getSign();
        //短信模板 ID
        String templateID = smsProperties.getTemplateID();
        //+86为国家码，182********为手机号，最多不要超过200个手机号

        String[] phoneNumbers = {jointMobile};
        //模板参数: 若无模板参数，则设置为空
        // 对应模板中{1}
//        String[] templateParams = {code};
        try {
            //必要步骤： 实例化一个认证对象，入参需要传入腾讯云账户密钥对 secretId 和 secretKey
            Credential cred = new Credential(secretId, secretKey);

            ClientProfile clientProfile = new ClientProfile();
            //SDK 默认用 TC3-HMAC-SHA256 进行签名 非必要请不要修改该字段
            clientProfile.setSignMethod("HmacSHA256");
            // 实例化 SMS 的 client 对象 第二个参数是地域信息，可以直接填写字符串 ap-guangzhou，或者引用预设的常量
            SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
            //实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数 您可以直接查询 SDK 源码确定接口有哪些属性可以设置
            SendSmsRequest req = new SendSmsRequest();

            // 短信应用 ID: 在 [短信控制台] 添加应用后生成的实际 SDKAppID，例如1400006666
            req.setSmsSdkAppid(appid);

            // 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名，可登录 [短信控制台] 查看签名信息
            req.setSign(sign);

            //短信模板 ID: 必须填写已审核通过的模板 ID，可登录 [短信控制台] 查看模板 ID
            req.setTemplateID(templateID);

            //下发手机号码，采用 e.164 标准，+[国家或地区码][手机号] 例如+8613711112222
            req.setPhoneNumberSet(phoneNumbers);

            req.setTemplateParamSet(params.keySet().toArray(new String[0]));

            // 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的 返回的 res 是一个SendSmsResponse 类的实例，与请求对象对应
            SendSmsResponse res = client.SendSms(req);
            //获取响应结果
            SendStatus[] sendStatusSet = res.getSendStatusSet();
            log.info("短信发送返回的响应：" + sendStatusSet[0].getCode());

            String codeInfo = "Ok";
            if (codeInfo.equals(sendStatusSet[0].getCode())) {
                return true;
            }
        } catch (TencentCloudSDKException e) {
            log.error("腾讯云短信发送sdk调用失败：" + e.getErrorCode() + "," + e.getMessage());
            throw new YyghException(ResultCodeEnum.CODE_ERROR);
        }
        return false;
    }
}

